home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-14 | 11.9 KB | 396 lines | [TEXT/CWIE] |
- /*
- Hiep's Special LDEF
- Written by: Hiep Dam
- Date: Long time ago (Dec 93?)
- Public domain.
-
- Previous incarnation as a pict list def, now a simple icon list def. Well,
- not so simple. Each cell should contain the IconListData data; this list
- def depends on each cell having at least this structure (you can extend it
- if you want).
-
- The IconListData structure basically notes how to hilite and frame the
- cell (thus, each cell could be framed and/or hilited differently, though
- this is NOT recommended!). It also contains the "icl8" rsrc id of the icon
- you want to use. If you frame the cell, make sure you specify the frameWidth.
- Also, if you cells are not 32x32 or 16x16 (std icon sizes) then you should
- specify the iconSize.
-
- Version History:
- 1.5 June 5 94: Changed from using PICTs to using icl8 icon families
-
- 2.0 Nov 14 95: Added ability to draw name as well, updated API and
- drawing, selecting code. Pretty much complete overhaul.
- Thanks to Steven Falkenburg & Norman Franke, whose simpler icon
- LDEF source code structure made simplizing my code much easier.
- */
-
- // ---------------------------------------------------------------------------
-
- #include <Icons.h>
- #include "icl8 LDEF.h"
-
- enum {
- kIconNameHeight = 10
- };
-
- // Used for kSelectbyFramingSpecial
- enum {
- kFrameHiliteRed = 39321, kFrameHiliteGreen = 52428, kFrameHiliteBlue = 65535,
- kFrameTingeRed = 26214, kFrameTingeGreen = 26214, kFrameTingeBlue = 39321,
- kFrameBodyRed = 48059, kFrameBodyGreen = 48059, kFrameBodyBlue = 48059,
- kBlack = 0
- };
-
- // ---------------------------------------------------------------------------
-
- static void CenterRect(Rect *innerRect, const Rect *outerRect);
-
- static void GetIconDestRect(
- const IconListDataPtr theIcon,
- const Rect *cellRect,
- Rect *destRect);
-
- static void PlotIconName(
- GrafPtr ownerPort,
- const IconListDataPtr theIcon,
- const Rect *iconRect,
- const Rect *cellRect,
- Rect *iconNameRect);
-
- void DrawCell(
- ListHandle listH,
- const Rect *cellR,
- Cell theCell,
- short dataLen,
- Boolean select);
-
- // ---------------------------------------------------------------------------
-
- void CenterRect(Rect *innerRect, const Rect *outerRect) {
- short outerRectWidth = outerRect->right - outerRect->left;
- short outerRectHeight = outerRect->bottom - outerRect->top;
- short innerRectWidth = innerRect->right - innerRect->left;
- short innerRectHeight = innerRect->bottom - innerRect->top;
- short hDiff = (outerRectWidth - innerRectWidth) / 2;
- short vDiff = (outerRectHeight - innerRectHeight) / 2;
- innerRect->left = outerRect->left + hDiff;
- innerRect->right = innerRect->left + innerRectWidth;
- innerRect->top = outerRect->top + vDiff;
- innerRect->bottom = innerRect->top + innerRectHeight;
- } // END CenterRect
-
- // ---------------------------------------------------------------------------
- // ---------------------------------------------------------------------------
-
- /*
- Determine destination area to draw icon in (centered inside the cell rect).
- If the icon specifies to draw the name as well, the dest area is moved up
- a bit to accomodate the name.
- */
- void GetIconDestRect(
- const IconListDataPtr theIcon,
- const Rect *cellRect,
- Rect *destRect) {
-
- short cellWidth = cellRect->right - cellRect->left;
- short cellHeight = cellRect->bottom - cellRect->top;
- short whatIconSize;
-
- if (theIcon->iconSize != kIconBasedOnCellSize)
- whatIconSize = theIcon->iconSize;
- else if ((cellWidth > kIcon32Size) && (cellHeight > kIcon32Size))
- whatIconSize = kIcon32Size;
- else
- whatIconSize = kIcon16Size;
-
- switch(whatIconSize) {
- case kIcon32Size:
- // Explicitly use 32 pixel size
- SetRect(destRect, 0, 0, kIcon32Size, kIcon32Size);
- // Accomodate space for name
- if (theIcon->drawName)
- destRect->bottom += kIconNameHeight;
- CenterRect(destRect, cellRect);
- break;
-
- case kIcon16Size:
- // Explicitly use 16 pixel size
- SetRect(destRect, 0, 0, kIcon16Size, kIcon16Size);
- if (theIcon->drawName)
- destRect->bottom += kIconNameHeight;
- CenterRect(destRect, cellRect);
- break;
- }
-
- if (theIcon->drawName) {
- destRect->bottom -= kIconNameHeight;
- }
- } // END GetIconDestRect
-
- // ---------------------------------------------------------------------------
-
- /*
- Draw the icon's name, based on the cell and icon rects. The name is
- positioned centered and below the icon's rect.
-
- The adjusted rect of the name is passed out to <iconNameRect> for later
- hiliting if needed. If there is no name, an empty rect is passed.
- */
- static void PlotIconName(
- GrafPtr ownerPort,
- const IconListDataPtr theIcon,
- const Rect *iconRect,
- const Rect *cellRect,
- Rect *iconNameRect) {
-
- short saveFont, saveFontSize, saveFontFace;
-
- // Save current font, size, & face settings & set them to what we need to
- saveFont = ownerPort->txFont;
- saveFontSize = ownerPort->txSize;
- saveFontFace = ownerPort->txFace;
- TextFont(geneva);
- TextSize(9);
- TextFace(0);
-
- // Get icon name
- Str255 iconName;
- Handle iconHandle;
- short iconID;
- ResType iconType;
- iconHandle = GetResource('icl8', theIcon->id);
- GetResInfo(iconHandle, &iconID, &iconType, iconName);
- ReleaseResource(iconHandle);
-
- // Center name
- Rect nameRect;
- if (iconName[0] == 0) {
- SetRect(&nameRect, 0, 0, 0, 0);
- }
- else {
- short nameWidth, cellWidth;
- nameWidth = StringWidth(iconName);
- cellWidth = cellRect->right - cellRect->left;
- // Make sure name's width isn't longer than cell's; otherwise condense
- if (nameWidth > cellWidth) {
- TextFace(condense);
- // Get width again (if still larger, clip it)
- nameWidth = StringWidth(iconName);
- if (nameWidth > cellWidth)
- nameWidth = cellWidth;
- }
- SetRect(&nameRect, 0, 0, nameWidth, kIconNameHeight);
- CenterRect(&nameRect, cellRect);
- nameRect.top = iconRect->bottom;
- nameRect.bottom = nameRect.top + kIconNameHeight;
-
- // Draw it (finally...)
- MoveTo(nameRect.left, nameRect.bottom);
- DrawString(iconName);
-
- InsetRect(&nameRect, -3, 0);
- nameRect.bottom += 2;
- }
-
- TextFont(saveFont);
- TextSize(saveFontSize);
- TextFace(saveFontFace);
-
- *iconNameRect = nameRect;
- } // END PlotIconName
-
- // ---------------------------------------------------------------------------
-
- void DrawCell(
- ListHandle listH,
- const Rect *cellR,
- Cell theCell,
- short dataLen,
- Boolean select) {
-
- GrafPtr savePort;
- PenState savePenState;
- OSErr myErr;
- IconListData theIcon;
- Rect destRect;
- Rect iconNameRect;
- RgnHandle saveClip;
-
- GetPort(&savePort);
- SetPort((**listH).port);
- saveClip = NewRgn();
- GetClip(saveClip);
- ClipRect(cellR); // Set clip region to cell rectangle, so no drawing outside cell
- GetPenState(&savePenState);
- PenNormal();
-
- dataLen = sizeof(IconListData); // Only get enough stuff for our own purposes
- LGetCell(&theIcon, &dataLen, theCell, listH);
-
- // --------------------------------------------------
- // STEP 1: Draw cell
- // --------------------------------------------------
- EraseRect(cellR);
- GetIconDestRect(&theIcon, cellR, &destRect);
- // Here's the actual call that'll do the work for us. Note that myErr is
- // ignored by this LDEF.
- myErr = PlotIconID(&destRect, atNone, ttNone, theIcon.id);
- if (theIcon.drawName)
- PlotIconName((**listH).port, &theIcon, &destRect, cellR, &iconNameRect);
-
- // --------------------------------------------------
- // STEP 2: Hilite cell and name accordingly (if need be)
- // --------------------------------------------------
- if (select) {
- switch(theIcon.selType) {
- case kSelectByInvertBW:
- case kSelectByInvertHilite:
- if (theIcon.selType == kSelectByInvertHilite)
- LMSetHiliteMode(LMGetHiliteMode() ^ (1 << hiliteBit));
- InvertRect(cellR);
- break;
-
- case kSelectByDarkenIcon:
- myErr = PlotIconID(&destRect, atNone, ttSelected, theIcon.id);
- // Hilite name
- if (theIcon.drawName) {
- LMSetHiliteMode(LMGetHiliteMode() ^ (1 << hiliteBit));
- InvertRect(&iconNameRect);
- }
- break;
-
- case kSelectByFramingBW:
- // Frame cell by using a black border. Standard.
- ForeColor(blackColor);
- PenSize(theIcon.frameWidth, theIcon.frameWidth);
- FrameRect(cellR);
- break;
-
- case kSelectbyFramingHilite:
- // Frame the cell by using the hilite color the user chose in the
- // General control panel. Note that this will work on a black and
- // white mac, too
- LMSetHiliteMode(LMGetHiliteMode() ^ (1 << hiliteBit));
- PenSize(theIcon.frameWidth, theIcon.frameWidth);
- PenMode(srcXor);
- FrameRect(cellR);
- break;
-
- case kSelectByFramingSpecial:
- // Use Special: frame by drawing a special, funky-looking frame
- // that is copied after how the frame of a movable modal dialog looks.
- // Everything is hard coded into this LDEF. You can change this if you
- // wish. Note that it is up to the calling program to check if
- // it's running on a Color QuickDraw mac. This code does not check
- // whatsoever, so calling kUseSpecial on a black and white Mac will
- // result in a crash.
-
- RGBColor frameHilite, frameTinge, frameBody, frameBlack, foreSave;
- Rect frameRect = *cellR;
-
- frameBlack.red = frameBlack.green = frameBlack.blue = kBlack;
- frameHilite.red = kFrameHiliteRed;
- frameHilite.green = kFrameHiliteGreen;
- frameHilite.blue = kFrameHiliteBlue;
- frameTinge.red = kFrameTingeRed;
- frameTinge.green = kFrameTingeGreen;
- frameTinge.blue = kFrameTingeBlue;
- frameBody.red = kFrameBodyRed;
- frameBody.green = kFrameBodyGreen;
- frameBody.blue = kFrameBodyBlue;
-
- GetForeColor(&foreSave);
-
- // Step 1: Draw outer black frame
- RGBForeColor(&frameBlack);
- FrameRect(&frameRect);
-
- // Step 2: Draw outer upper left hilite
- RGBForeColor(&frameHilite);
- InsetRect(&frameRect, 1, 1); frameRect.right--; frameRect.bottom--;
- // Top edge
- MoveTo(frameRect.left, frameRect.top);
- LineTo(frameRect.right - 1, frameRect.top);
- // Left edge
- MoveTo(frameRect.left, frameRect.top);
- LineTo(frameRect.left, frameRect.bottom - 1);
-
- // Step 3: Draw outer lower right tinge
- RGBForeColor(&frameTinge);
- // Right edge
- MoveTo(frameRect.right, frameRect.bottom);
- LineTo(frameRect.right, frameRect.top);
- // Bottom edge
- MoveTo(frameRect.right, frameRect.bottom);
- LineTo(frameRect.left, frameRect.bottom);
-
- // Step 4: Draw inner body frame
- RGBForeColor(&frameBody);
- InsetRect(&frameRect, 1, 1); frameRect.right++; frameRect.bottom++;
- FrameRect(&frameRect);
-
- // Step 5: Draw inner upper left tinge
- RGBForeColor(&frameTinge);
- InsetRect(&frameRect, 1, 1); frameRect.right--; frameRect.bottom--;
- // Top edge
- MoveTo(frameRect.left, frameRect.top);
- LineTo(frameRect.right, frameRect.top);
- // Left edge
- MoveTo(frameRect.left, frameRect.top);
- LineTo(frameRect.left, frameRect.bottom);
-
- // Step 6: Draw inner lower right hilite
- RGBForeColor(&frameHilite);
- // Right edge
- MoveTo(frameRect.right, frameRect.bottom);
- LineTo(frameRect.right, frameRect.top - 1);
- // Bottom edge
- MoveTo(frameRect.right, frameRect.bottom);
- LineTo(frameRect.left - 1, frameRect.bottom);
-
- // Step 7: Draw inner black frame
- RGBForeColor(&frameBlack);
- InsetRect(&frameRect, 1, 1); frameRect.right++; frameRect.bottom++;
- FrameRect(&frameRect);
-
- RGBForeColor(&foreSave);
-
- // Uncomment if you want this method to hilite the icon name as well
- /*
- if (theIcon.drawName) {
- LMSetHiliteMode(LMGetHiliteMode() ^ (1 << hiliteBit));
- InvertRect(&iconNameRect);
- }
- */
- break;
- } // END switch
- }
-
- SetClip(saveClip);
- SetPenState(&savePenState);
- SetPort(savePort);
- } // END DrawCell
-
- // ---------------------------------------------------------------------------
-
- #ifdef powerc
- ProcInfoType __procinfo = uppListDefProcInfo;
- #endif
-
- pascal void main(short lMsg, Boolean lSelect, Rect *lRect, Cell lCell, short dataOffset,
- short dataLen, ListHandle theList) {
- switch(lMsg) {
- case lDrawMsg:
- case lHiliteMsg:
- DrawCell(theList, lRect, lCell, dataLen, lSelect);
- break;
-
- default:
- break;
- } // END switch
- } // END main entry point
-
-
- // ---------------------------------------------------------------------------
- // END icl8 LDEF.cpp